package com.it.travel.aop;

import cn.hutool.jwt.JWT;
import com.it.travel.common.RequiredPermission;
import com.it.travel.dao.UserMapper;
import com.it.travel.handle.PermissionException;
import com.it.travel.pojo.Permission;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;

@Aspect
@Component
public class PermissionAop {
    @Resource
    private UserMapper userMapper;

    /**
     * 在我们的方法前后实现拦截
     * 拦截就是在我们方法上是否加上自定义注解
     * 如果有加上该自定义注解，则会执行around
     *
     * @param joinPoint
     * @return
     */

    @Around(value = "@annotation(com.it.travel.common.RequiredPermission)")
    public Object around(ProceedingJoinPoint joinPoint) throws Exception {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        String token = request.getHeader("Authorization");  // 获取token
        JWT of = JWT.of(token);
        String username = (String) of.getPayload("username");
        List<Permission> permissionList = userMapper.queryPermissionListByUserName(username);
        Signature signature = joinPoint.getSignature(); // 获取签名
        MethodSignature methodSignature = (MethodSignature) signature; // 获取方法签名
        Method method = methodSignature.getMethod(); // 获取对应的方法
        RequiredPermission declaredAnnotation = method.getDeclaredAnnotation(RequiredPermission.class);
        String value = declaredAnnotation.value();
//        System.out.println("declaredAnnotation.value() = " + declaredAnnotation.value());
        for (Permission permission : permissionList) {
            if (value.equals(permission.getPermissionCode())) {  // 如果当前用户所具有的权限包含，那么我们就执行方法
                Object proceed = null;
                try {
                    proceed = joinPoint.proceed();
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
                return proceed;
            }
        }
        throw new PermissionException("权限不足");
    }
}
